iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
Modern Web

VUE見我,走在時代的前端系列 第 15

DAY 15 使用 Teleport API 在 Vue 3 中實現 DOM 控制

  • 分享至 

  • xImage
  •  

Vue 3 引入了強大的 Teleport API,它讓開發者可以輕鬆地將一部分的 DOM 結構渲染到應用中的其他位置,甚至超出 Vue 應用的根範圍。在某些情況下,像是模態窗口、工具提示、彈出式菜單等 UI 元素,我們希望它們不受當前的父組件約束,可以被移動到頁面其他位置顯示。Teleport API 正是為了應對這樣的場景而設計的。

什麼是 Teleport?

Teleport 是 Vue 3 提供的一個內建組件,它允許我們將子組件或 DOM 結構“傳送”到應用的其他地方。這一功能使得處理如彈窗、全局通知等需求變得更加直觀且方便,因為這些元素可以脫離當前組件的層級限制。

使用 Teleport 時,僅需指定目標 DOM 節點,Vue 會自動將子元素渲染到該節點,而不會影響組件的響應式數據和狀態。

Teleport 的基本使用方式

Teleport 的使用非常簡單,我們可以通過 元素來指定要移動的 DOM 節點。以下是基本語法範例:

<template>
  <div>
    <h1>主內容</h1>
    <teleport to="body">
      <div class="modal">
        <h2>這是彈窗</h2>
        <p>彈窗內容顯示在 body 中,而不是當前的父容器內。</p>
      </div>
    </teleport>
  </div>
</template>

在這個範例中, 組件將其內部的 div 元素傳送到 body 節點。雖然這段代碼是在當前父容器中定義的,但實際渲染時,它會出現在 body 節點中。

Teleport 的使用場景

彈窗

當需要實現全局的彈窗時,我們不希望彈窗的 DOM 結構被嵌套在其他深層次的父組件中,因為這樣可能會影響彈窗的定位和樣式。使用 Teleport,可以將彈窗直接渲染到 body,從而避免這些問題。

<template>
  <div>
    <button @click="showModal = true">打開彈窗</button>
    
    <teleport to="body">
      <div v-if="showModal" class="modal">
        <h2>彈窗標題</h2>
        <p>這是一個全局彈窗的內容。</p>
        <button @click="showModal = false">關閉彈窗</button>
      </div>
    </teleport>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showModal: false
    };
  }
};
</script>

<style>
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  padding: 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
</style>

在這個範例中,當用戶點擊按鈕時,彈窗會顯示在頁面的正中央。透過 Teleport,彈窗的 DOM 被直接渲染到 body 中,這使得定位和樣式的控制變得簡單明了。

全局通知

全局通知或提示信息通常需要顯示在頁面的頂層,並且通常不應該受到組件層次結構的限制。Teleport 同樣適合處理這樣的需求。

<template>
  <div>
    <button @click="showNotification = true">顯示通知</button>
    
    <teleport to="body">
      <div v-if="showNotification" class="notification">
        <p>這是一個全局通知。</p>
      </div>
    </teleport>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showNotification: false
    };
  }
};
</script>

<style>
.notification {
  position: fixed;
  top: 20px;
  right: 20px;
  background-color: #44c767;
  color: white;
  padding: 10px 20px;
  border-radius: 4px;
}
</style>

這個範例展示了如何使用 Teleport 來創建一個全局通知。當通知顯示時,它會固定在頁面右上角,不會受到父組件的影響。

Teleport 的進階用法

傳送到動態的 DOM 節點

Teleport 不僅可以將 DOM 結構傳送到靜態的節點,還可以動態地指定目標節點。這使得在複雜的應用中,我們可以根據不同的場景靈活選擇 DOM 節點。

<template>
  <div>
    <label for="target">選擇傳送目標:</label>
    <select v-model="target">
      <option value="body">Body</option>
      <option value="#sidebar">Sidebar</option>
    </select>

    <teleport :to="target">
      <div class="teleported-content">
        <p>這個內容會根據選擇傳送到不同位置。</p>
      </div>
    </teleport>
  </div>
</template>

<script>
export default {
  data() {
    return {
      target: 'body'
    };
  }
};
</script>

<style>
.teleported-content {
  background-color: lightblue;
  padding: 10px;
  border: 1px solid #ccc;
}
</style>

在這個範例中,用戶可以動態選擇傳送目標,Vue 會根據 target 的值將內容傳送到 body 或 #sidebar 等不同的 DOM 節點中。

使用 slot 在 Teleport 中傳送插槽內容

Teleport 可以與插槽(slot)結合使用,允許將動態內容傳送到指定的位置。

<template>
  <div>
    <teleport to="body">
      <slot name="modal-content"></slot>
    </teleport>
  </div>
</template>

<!-- 父組件 -->
<template>
  <Modal>
    <template v-slot:modal-content>
      <div class="custom-modal">
        <h3>插槽內容傳送到 body 中</h3>
      </div>
    </template>
  </Modal>
</template>

這種模式使得 Teleport 的使用更加靈活,允許開發者通過插槽的方式將內容傳送到不同的節點。

結語

Vue 3 的 Teleport API 提供了一種優雅的方式來控制 DOM 元素的位置,讓開發者可以在不改變組件結構的情況下實現更靈活的布局和 UI 控制。通過 Teleport,我們可以輕鬆實現模態框、全局通知、工具提示等常見場景,並且能夠動態指定傳送目標。這使得 Vue 3 在處理複雜的 DOM 操作時更加得心應手。


上一篇
DAY14 Vue 3 中的表單驗證:如何實現自定義驗證邏輯
下一篇
DAY 16 如何在 Vue 3 中實現全局和局部混入(Mixins)
系列文
VUE見我,走在時代的前端30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言